package com.vf.s.common.vector.kml;

import de.micromata.opengis.kml.v_2_2_0.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
 
/**
 * @program: my_project
 * @description: KML文件解析：先获取kml文件的根节点，依次遍历当前节点的子节点的信息，
 * 如果遇到节点属于Folder、Document则继续解析其子节点；反之则解析PlaceMark节点（主要解析LineString、Point、Polygon）。
 * @create: 2018-12-01 12:39
 **/
public class KmlParser {
    //以下三行都是自定义的KML类，用于获取名称name、所有点points、样式颜色color
    private List<KmlPoint> kmlPointList = new ArrayList<>();
    private List<KmlLine> kmlLineList = new ArrayList<>();
    private List<KmlPolygon> kmlPolygonList = new ArrayList<>();
    private KmlProperty kmlProperty = new KmlProperty();
 
    /**
     * 保存kml数据到临时表
     *
     * @param file 上传的文件实体
     * @return 自定义的KML文件实体
     */
    public KmlProperty parseKmlForJAK(File file) {
        Kml kml = Kml.unmarshal(file);
        Feature feature = kml.getFeature();
        parseFeature(feature);
        kmlProperty.setKmlPoints(kmlPointList);
        kmlProperty.setKmlLines(kmlLineList);
        kmlProperty.setKmlPolygons(kmlPolygonList);
        return kmlProperty;
    }
 
    /**
     * 解析kml节点信息
     *
     * @param feature 需要解析到要素信息
     * @return
     */
    private  void parseFeature(Feature feature) {
        if (feature != null) {
            //判断根节点是否为Document
            if (feature instanceof Document) {
                List<Feature> featureList = ((Document) feature).getFeature();
                //遍历已获取的节点信息(节点信息为List)，将list使用forEach进行遍历（同for、while）
                featureList.forEach(documentFeature -> {
                            //判断遍历节点是否为PlaceMark，否则迭代解析
                			System.out.println("断遍历节点是否为PlaceMark，否则迭代解析");
                            if (documentFeature instanceof Placemark) {
                                getPlaceMark((Placemark) documentFeature);
                            } else {
                                parseFeature(documentFeature);
                            }
                        }
                );
            } else if (feature instanceof Folder) {
                //原理同上
                List<Feature> featureList = ((Folder) feature).getFeature();
                featureList.forEach(documentFeature -> {
                            if (documentFeature instanceof Placemark) {
                                getPlaceMark((Placemark) documentFeature);
                            }
                            {
                                parseFeature(documentFeature);
                            }
                        }
                );
            }
        }
    }
 
    /**
     * 解析PlaceMark节点下的信息
     *
     * @return
     */
    private void getPlaceMark(Placemark placemark) {
        Geometry geometry = placemark.getGeometry();
        parseGeometry(placemark,geometry);
    }
 
    /**
     * 解析PlaceMark节点下的信息
     *
     * @return
     */
    private void parseGeometry(Placemark placemark,Geometry geometry) {
        if (geometry != null) {
            if (geometry instanceof Polygon) {
                Polygon polygon = (Polygon) geometry;
                Boundary outerBoundaryIs = polygon.getOuterBoundaryIs();
                if (outerBoundaryIs != null) {
                    LinearRing linearRing = outerBoundaryIs.getLinearRing();
                    if (linearRing != null) {
                        List<Coordinate> coordinates = linearRing.getCoordinates();
                        if (coordinates != null) {
                            outerBoundaryIs = ((Polygon) geometry).getOuterBoundaryIs();
                            addPolygonToList(placemark,kmlPolygonList, outerBoundaryIs);
                        }
                    }
                }
            } else if (geometry instanceof LineString) {
                LineString lineString = (LineString) geometry;
                List<Coordinate> coordinates = lineString.getCoordinates();
                if (coordinates != null) {
                    coordinates = ((LineString) geometry).getCoordinates();
                    addLineStringToList(placemark,kmlLineList, coordinates);
                }
            } else if (geometry instanceof Point) {
                Point point = (Point) geometry;
                List<Coordinate> coordinates = point.getCoordinates();
                if (coordinates != null) {
                    coordinates = ((Point) geometry).getCoordinates();
                    addPointToList(placemark,kmlPointList, coordinates);
                }
            } else if (geometry instanceof MultiGeometry) {
                List<Geometry> geometries = ((MultiGeometry) geometry).getGeometry();
                for (Geometry geometryToMult : geometries) {
                    Boundary outerBoundaryIs;
                    List<Coordinate> coordinates;
                    if (geometryToMult instanceof Point) {
                        coordinates = ((Point) geometryToMult).getCoordinates();
                        addPointToList(placemark,kmlPointList, coordinates);
                    } else if (geometryToMult instanceof LineString) {
                        coordinates = ((LineString) geometryToMult).getCoordinates();
                        addLineStringToList(placemark,kmlLineList, coordinates);
                    } else if (geometryToMult instanceof Polygon) {
                        outerBoundaryIs = ((Polygon) geometryToMult).getOuterBoundaryIs();
                        addPolygonToList(placemark,kmlPolygonList, outerBoundaryIs);
                    }
                }
            }
        }
    }
 
    /**
     * 将kml中所有面添加到一个list
     *
     * @return
     */
    private void addPolygonToList(Placemark placemark,List<KmlPolygon> kmlPolygonList, Boundary outerBoundaryIs) {
        LinearRing linearRing;
        List<Coordinate> coordinates;
        linearRing = outerBoundaryIs.getLinearRing();//面
        coordinates = linearRing.getCoordinates();
        KmlPolygon kmlPolygon = new KmlPolygon();
        kmlPolygon.setPoints(coordinates);
        kmlPolygon.setPlacemark(placemark);
        kmlPolygonList.add(kmlPolygon);
    }
 
    /**
     * 将kml中所有线添加到一个list
     *
     * @return
     */
    private void addLineStringToList(Placemark placemark,List<KmlLine> kmlLineList, List<Coordinate> coordinates) {
        KmlLine kmlLine = new KmlLine();
        kmlLine.setPoints(coordinates);
        kmlLine.setPlacemark(placemark);
        kmlLineList.add(kmlLine);
    }
 
    /**
     * 将kml中所有点添加到一个list
     *
     * @return
     */
    private void addPointToList(Placemark placemark,List<KmlPoint> kmlPointList, List<Coordinate> coordinates) {
    	KmlPoint kmlPoint = new KmlPoint();
    	kmlPoint.setPlacemark(placemark);
        kmlPoint.setPoints(coordinates);
        kmlPointList.add(kmlPoint);
    }
    
}